package cn.tedu.csmall.passport.service.impl;

import cn.tedu.csmall.passport.ex.ServiceException;
import cn.tedu.csmall.passport.mapper.AdminMapper;
import cn.tedu.csmall.passport.pojo.dto.AdminAddNewDTO;
import cn.tedu.csmall.passport.pojo.dto.AdminLoginDTO;
import cn.tedu.csmall.passport.pojo.entity.Admin;
import cn.tedu.csmall.passport.pojo.vo.AdminListItemVO;
import cn.tedu.csmall.passport.pojo.vo.AdminStandardVO;
import cn.tedu.csmall.passport.service.IAdminService;
import cn.tedu.csmall.passport.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;


@Slf4j
@Service
public class AdminServiceImpl implements IAdminService {

    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void login(AdminLoginDTO adminLoginDTO) {
        log.debug("开始处理【管理员登录】的业务，参数：{}", adminLoginDTO);
        //执行认证
        Authentication authentication = new UsernamePasswordAuthenticationToken(
                adminLoginDTO.getUsername(), adminLoginDTO.getPassword());
        Authentication authenticateResult = authenticationManager.authenticate(authentication);
        log.debug("认证通过！");

        SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(authenticateResult);
    }

    @Override
    public void addNew(AdminAddNewDTO adminAddNewDTO) {
        log.debug("开始处理【插入管理员】业务，参数：{}", adminAddNewDTO);
        //查询是否用户名冲突
        int count = adminMapper.countByUsername(adminAddNewDTO.getUsername());
        if(count > 0){
            String message = "添加管理员失败，尝试使用的用户名已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //查询是否电话号码冲突
        count = adminMapper.countByPhone(adminAddNewDTO.getPhone());
        if(count > 0){
            String message = "添加管理员失败，尝试使用的电话号码已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        //查询是否电子邮箱冲突
        count = adminMapper.countByEmail(adminAddNewDTO.getEmail());
        if(count > 0){
            String message = "添加管理员失败，尝试使用的电子邮箱已经被占用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        Admin admin = new Admin();
        BeanUtils.copyProperties(adminAddNewDTO, admin);
        // 将原密码加密，并修正属性值：admin.setPassword(xxx)
        String rawPassword = admin.getPassword();
        String encodedPassword = passwordEncoder.encode(rawPassword);
        admin.setPassword(encodedPassword);
        admin.setLoginCount(0);
        adminMapper.insert(admin);
    }

    @Override
    public void delete(Long id) {
        log.debug("开始处理【删除管理员】业务，参数：{}", id);
        // 根据管理员id检查管理员数据是否存在
        AdminStandardVO queryResult = adminMapper.getStandardById(id);
        if(queryResult == null){
            String message = "删除管理员失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        log.debug("即将执行删除，参数：{}", id);
        adminMapper.deleteById(id);
    }

    @Override
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    @Override
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }

    @Override
    public List<AdminListItemVO> list() {
        log.debug("开始处理【查询管理员列表】业务，参数：无");
        List<AdminListItemVO> list = adminMapper.list();
        return list;
    }

    private void updateEnableById(Long id, Integer enable){
        String[] enableText = {"禁用", "启用"};
        log.debug("开始处理" + enableText[enable] + "管理员的业务，管理员ID：{}，目标状态：{}", id, enable);
        // 根据管理员id检查管理员数据是否存在
        AdminStandardVO queryResult = adminMapper.getStandardById(id);
        if(queryResult == null){
            String message = enableText[enable] + "管理员失败，尝试访问的数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        // 检查管理员数据的当前状态是否与参数enable表示的状态相同
        if(queryResult.getEnable().equals(enable)){
            String message = enableText[enable] + "管理员失败，当前管理员已经是" + enableText[enable] + "状态！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        Admin admin = new Admin();
        admin.setId(id);
        admin.setEnable(enable);
        log.debug("即将修改数据，参数：{}", admin);
        adminMapper.update(admin);
    }

}
